package com.fagejiang.entity;

import lombok.Data;
import org.junit.Test;

import javax.persistence.Table;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Locale;

/**
 * TODO
 *
 * @author 发哥讲Java
 * @version 1.0
 * @date 2021-03-12 11:20
 */
public class OutPutYaml {

    @Test
    public void testWxPayLogoutInfo() {
        final Class<WxPayLogoutInfo> wxPayLogoutInfoClass = WxPayLogoutInfo.class;
        GpKafkaYaml gpKafkaYaml = new GpKafkaYaml(wxPayLogoutInfoClass);
        gpKafkaYaml.setMapping(getMapping(gpKafkaYaml));
        ouuPutYamlFile(gpKafkaYaml.getTABLENAME() + ".yaml", gpKafkaYaml.result());
    }

    @Test
    public void testWxPayRegInfo() {
        final Class<WxPayRegInfo> wxPayRegInfoClass = WxPayRegInfo.class;
        GpKafkaYaml gpKafkaYaml = new GpKafkaYaml(wxPayRegInfoClass);
        gpKafkaYaml.setMapping(getMapping(gpKafkaYaml));
        ouuPutYamlFile(gpKafkaYaml.getTABLENAME() + ".yaml", gpKafkaYaml.result());
    }

    @Test
    public void testWxTrades() {
        final Class<WxTrades> wxTradesClass =WxTrades.class;
        GpKafkaYaml gpKafkaYaml = new GpKafkaYaml(wxTradesClass);
        gpKafkaYaml.setMapping(getMapping(gpKafkaYaml));
        ouuPutYamlFile(gpKafkaYaml.getTABLENAME() + ".yaml", gpKafkaYaml.result());
    }

    public void ouuPutYamlFile(String fileName, String result) {
        String path = "D:\\development\\workspace\\fagejiang\\frames\\springboot-jpa\\src\\main\\java\\com\\fagejiang\\model\\";
        try (FileOutputStream fos = new FileOutputStream(new File(path + fileName))) {
            fos.write(result.getBytes());
            System.out.println(fileName + "输出成功");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public String getMapping(GpKafkaYaml gpKafkaYaml) {
        Class<?> cls = gpKafkaYaml.getCls();
        String jsonName = gpKafkaYaml.getJSONNAME();
        final Field[] fields = cls.getDeclaredFields();
        StringBuilder str = new StringBuilder();
        for (Field field : fields) {
            if (!"id".equals(field.getName())) {
                str.append("      - NAME: " + apply(field.getName()) + "\n");
                str.append("        EXPRESSION: (" + jsonName + "->>'" + field.getName() + "')::" + getTypeByFiledType(field) + "\n");
            }
        }
        return str.toString();
    }

    public String getTableName(Class<?> cls) {
        String tableName = null;
        for (Annotation annotation : cls.getDeclaredAnnotations()) {
            if (annotation.annotationType() == Table.class) {
                Table table = (Table) annotation;
                tableName = table.name();
            }
        }
        if (tableName == null) {
            return null;
        }
        return tableName;
    }


    public String getTypeByFiledType(Field field) {
        switch (field.getType().getName()) {
            case "java.lang.String":
                return "text";
            case "java.lang.Long":
            case "java.lang.Integer":
                return "bigint";
            default:
                return "text";
        }
    }

    @Test
    public void testApply(){
        System.out.println("apply(\"appTypeBig\") = " + apply("appType"));
    }

    private String apply(String name) {
        StringBuilder builder = new StringBuilder(name.replace('.', '_'));
        for (int i = 1; i < builder.length() - 1; ++i) {
            if (this.isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
                builder.insert(i++, '_');
            }
        }
        return builder.toString().toLowerCase(Locale.ROOT);
    }

    private boolean isUnderscoreRequired(char before, char current, char after) {
        return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
    }

    @Data
    private class GpKafkaYaml {
        String DATABASE = "nightHawk_shaoxing";
        String HOST = "192.168.0.44";
        String PORT = "5433";
        String BROKERS = "192.168.0.44:39092";
        String TABLENAME;
        String JSONNAME = "jdata";
        Class<?> cls;
        StringBuilder str = new StringBuilder();
        String mapping = null;
        StringBuilder end = new StringBuilder("  COMMIT:\n" +
                "    MAX_ROW: 10000\n" +
                "    MINIMAL_INTERVAL: 30000");

        public GpKafkaYaml(Class<?> cls) {
            this.cls = cls;
            TABLENAME = getTableName(cls);
        }

        public String result() {
            changedStringBuilder();
            return str.append(mapping).append(end).toString();
        }

        public void setDATABASE(String DATABASE) {
            this.DATABASE = DATABASE;
        }

        public void setHOST(String HOST) {
            this.HOST = HOST;
        }

        public void setPORT(String PORT) {
            this.PORT = PORT;
        }

        public void setBROKERS(String BROKERS) {
            this.BROKERS = BROKERS;
        }

        public void setTableName(String TABLENAME) {
            this.TABLENAME = TABLENAME;
        }

        public void setJSONNAME(String JSONNAME) {
            this.JSONNAME = JSONNAME;
        }

        public void changedStringBuilder() {
            str = new StringBuilder();
            str.append("DATABASE: " + DATABASE + "\n" +
                    "USER: gpadmin\n" +
                    "HOST: " + HOST + "\n" +
                    "PORT: " + PORT + "\n" +
                    "KAFKA:\n" +
                    "  INPUT:\n" +
                    "    SOURCE:\n" +
                    "      BROKERS: " + BROKERS + "\n" +
                    "      TOPIC: " + TABLENAME + "_topic\n" +
                    "    COLUMNS:\n" +
                    "      - NAME: " + JSONNAME + "\n" +
                    "        TYPE: json\n" +
                    "    FORMAT: json\n" +
                    "    ERROR_LIMIT: 10\n" +
                    "  OUTPUT:\n" +
                    "    TABLE: " + TABLENAME + "\n" +
                    "    MAPPING:\n");
        }
    }
}
